﻿using System;
using System.Configuration;
using System.Data;
using System.Globalization;

using BizElements.Core;

namespace BizElements.BusinessLayer
{
    /// <summary>
    /// Typed IDbTable class for the table/view 'LockManager'.
    /// </summary>
    [Serializable]
    sealed class LockManagerMeta : SealedDbTable
    {
        static LockManagerMeta()
        {
            ReadSequenceOverrideFromConfig();
            ReadColumnNamesFromConfig();
            ImmutableColumnProperties = CreateImmutableColumnProperties();
            ImmutableTableProperties = CreateImmutableTableProperties();
        }

        #region Configuration.

        static readonly string[] SequenceNameOverrides = new string[6];
        static readonly bool?[] AutoIncrementOverrides = new bool?[6];

        private static void ReadSequenceOverrideFromConfig()
        {
            SequenceNameOverrides[0] = ConfigurationManager.AppSettings["LockManager.LockId.SequenceName"];
            AutoIncrementOverrides[0] = (SequenceNameOverrides[0] != null) ? (bool?)true : null;
            SequenceNameOverrides[1] = ConfigurationManager.AppSettings["LockManager.ObjectType.SequenceName"];
            AutoIncrementOverrides[1] = (SequenceNameOverrides[1] != null) ? (bool?)true : null;
            SequenceNameOverrides[2] = ConfigurationManager.AppSettings["LockManager.ObjectId.SequenceName"];
            AutoIncrementOverrides[2] = (SequenceNameOverrides[2] != null) ? (bool?)true : null;
            SequenceNameOverrides[3] = ConfigurationManager.AppSettings["LockManager.LockedBy.SequenceName"];
            AutoIncrementOverrides[3] = (SequenceNameOverrides[3] != null) ? (bool?)true : null;
            SequenceNameOverrides[4] = ConfigurationManager.AppSettings["LockManager.LockedTill.SequenceName"];
            AutoIncrementOverrides[4] = (SequenceNameOverrides[4] != null) ? (bool?)true : null;
            SequenceNameOverrides[5] = ConfigurationManager.AppSettings["LockManager.LockMode.SequenceName"];
            AutoIncrementOverrides[5] = (SequenceNameOverrides[5] != null) ? (bool?)true : null;
        }

        static readonly string[] ColumnNames = new string[6];

        private static void ReadColumnNamesFromConfig()
        {
            ColumnNames[0] = LockManagerCatalog.GetColumnNameOverride("LockManager", "LockId") ?? "LockId";
            ColumnNames[1] = LockManagerCatalog.GetColumnNameOverride("LockManager", "ObjectType") ?? "ObjectType";
            ColumnNames[2] = LockManagerCatalog.GetColumnNameOverride("LockManager", "ObjectId") ?? "ObjectId";
            ColumnNames[3] = LockManagerCatalog.GetColumnNameOverride("LockManager", "LockedBy") ?? "LockedBy";
            ColumnNames[4] = LockManagerCatalog.GetColumnNameOverride("LockManager", "LockedTill") ?? "LockedTill";
            ColumnNames[5] = LockManagerCatalog.GetColumnNameOverride("LockManager", "LockMode") ?? "LockMode";
        }

        #endregion

        #region Singleton/immutable configuration objects.

        static readonly DbColumnConfiguration[] ImmutableColumnProperties;
        static readonly DbTableConfiguration ImmutableTableProperties;

        private static DbColumnConfiguration[] CreateImmutableColumnProperties()
        {
            return new DbColumnConfiguration[]
			{
				new DbColumnConfiguration(ColumnNames[0], DbType.Int32, typeof(int), false, 0, true, null, 0, true, false, false, "LockId", int.MinValue, int.MaxValue, false, SequenceNameOverrides[0]),
				new DbColumnConfiguration(ColumnNames[1], DbType.AnsiString, typeof(string), false, 1, AutoIncrementOverrides[1] ?? false, null, 255, false, false, false, "ObjectType", null, null, false, SequenceNameOverrides[1]),
				new DbColumnConfiguration(ColumnNames[2], DbType.AnsiString, typeof(string), false, 2, AutoIncrementOverrides[2] ?? false, null, 255, false, false, false, "ObjectId", null, null, false, SequenceNameOverrides[2]),
				new DbColumnConfiguration(ColumnNames[3], DbType.AnsiString, typeof(string), true, 3, AutoIncrementOverrides[3] ?? false, null, 50, false, false, false, "LockedBy", null, null, false, SequenceNameOverrides[3]),
				new DbColumnConfiguration(ColumnNames[4], DbType.DateTime, typeof(DateTime), true, 4, AutoIncrementOverrides[4] ?? false, null, 0, false, false, false, "LockedTill", new DateTime(1753, 1, 1), new DateTime(9999, 12, 31), false, SequenceNameOverrides[4]),
				new DbColumnConfiguration(ColumnNames[5], DbType.AnsiString, typeof(string), true, 5, AutoIncrementOverrides[5] ?? false, null, 50, false, false, false, "LockMode", null, null, false, SequenceNameOverrides[5]),
			};
        }

        private static DbTableConfiguration CreateImmutableTableProperties()
        {
            return new DbTableConfiguration
            (
                LockManagerCatalog.GetTableNameOverride("LockManager") ?? "LockManager",
                new LockManagerCatalog(),
                ImmutableColumnProperties,
                new int[] { 0 },
                new string[] { },
                /*is view*/ false
            );
        }

        #endregion

        #region Constructors.

        /// <summary>
        /// Initializes a new instance of LockManagerMeta class.
        /// </summary>
        public LockManagerMeta()
            : base(ImmutableTableProperties, null, false)
        {
        }

        /// <summary>
        /// Initializes a new instance of LockManagerMeta class.
        /// </summary>
        /// <param name="alias">Object alias. If NULL then it will be equal to the table name.</param>
        public LockManagerMeta(string alias)
            : base(ImmutableTableProperties, alias, false)
        {
        }

        /// <summary>
        /// Initializes a new instance of LockManagerMeta class.
        /// </summary>
        /// <param name="setPrefixedColumnAliases">Whether to change aliases of all columns so that they start with prefix (usually table name).</param>
        public LockManagerMeta(bool setPrefixedColumnAliases)
            : base(ImmutableTableProperties, null, setPrefixedColumnAliases)
        {
        }

        /// <summary>
        /// Initializes a new instance of LockManagerMeta class.
        /// </summary>
        /// <param name="alias">Object alias. If NULL then it will be equal to the table name.</param>
        /// <param name="setPrefixedColumnAliases">Whether to change aliases of all columns so that they start with prefix (usually table name).</param>
        public LockManagerMeta(string alias, bool setPrefixedColumnAliases)
            : base(ImmutableTableProperties, alias, setPrefixedColumnAliases)
        {
        }

        #endregion

        #region CreateForeignKeys.

        /// <summary>
        /// Initializes an array of relations used by foreign keys.
        /// Only relations to other generated IDbTable classes are created.
        /// </summary>
        protected override DbRelation[] CreateForeignKeys()
        {
            DbRelation[] foreignKeys = new DbRelation[0];

            return foreignKeys;
        }

        #endregion

        #region New* methods.

        /// <summary>
        /// Creates a new LockManagerEntity object.
        /// </summary>
        /// <returns>New entity.</returns>
        public override IEntity NewEntity()
        {
            return new LockManagerEntity(this);
        }

        /// <summary>
        /// Creates a new EntityReader&lt;LockManagerEntity&gt; object.
        /// </summary>
        /// <returns>An instance of EntityReader&lt;LockManagerEntity&gt; class.</returns>
        public override IObjectReader NewEntityReader()
        {
            // Use default EntityReader<T>() constructor when targeting SQLite database or when column types are compatible/convertible, but do not exactly match, entity property types.
            return new EntityReader<LockManagerEntity>(LockManagerEntity.NewEntity);
        }

        #endregion

        #region Clone.

        /// <summary>
        /// Creates another IDbTable object for the same table/view.
        /// </summary>
        /// <param name="cloneAlias">Clone alias.</param>
        /// <returns>Clone.</returns>
        public override IDbTable Clone(string cloneAlias)
        {
            return new LockManagerMeta(cloneAlias);
        }

        /// <summary>
        /// Creates another IDbTable object for the same table/view.
        /// </summary>
        /// <param name="cloneAlias">Clone alias.</param>
        /// <param name="setPrefixedAliases">Specifies whether cloned columns will have prefixed aliases.</param>
        /// <returns>Clone.</returns>
        public override IDbTable Clone(string cloneAlias, bool setPrefixedAliases)
        {
            return new LockManagerMeta(cloneAlias, setPrefixedAliases);
        }

        #endregion

        #region Columns.

        /// <summary>
        /// Gets metadata for 'LockId' column.
        /// </summary>
        public IDbColumn LockId
        {
            get { return this.Columns[0]; }
        }

        /// <summary>
        /// Gets metadata for 'ObjectType' column.
        /// </summary>
        public IDbColumn ObjectType
        {
            get { return this.Columns[1]; }
        }

        /// <summary>
        /// Gets metadata for 'ObjectId' column.
        /// </summary>
        public IDbColumn ObjectId
        {
            get { return this.Columns[2]; }
        }

        /// <summary>
        /// Gets metadata for 'LockedBy' column.
        /// </summary>
        public IDbColumn LockedBy
        {
            get { return this.Columns[3]; }
        }

        /// <summary>
        /// Gets metadata for 'LockedTill' column.
        /// </summary>
        public IDbColumn LockedTill
        {
            get { return this.Columns[4]; }
        }

        /// <summary>
        /// Gets metadata for 'LockMode' column.
        /// </summary>
        public IDbColumn LockMode
        {
            get { return this.Columns[5]; }
        }

        #endregion

        #region Foreign keys.

        #endregion

        #region Parent entity property name getters.

        #endregion

        #region Children.

        /// <summary>
        /// Gets tables which reference the current table.
        /// </summary>
        /// <returns>Array of tables or empty array if the current table is not referenced by other objects.</returns>
        public override IDbTable[] GetChildTables()
        {
            return new IDbTable[]
			{
			};
        }

        /// <summary>
        /// Gets relations where current table acts as a parent.
        /// </summary>
        /// <returns>Array of relations or empty array if the current table is not referenced by other objects.</returns>
        public override DbRelation[] GetChildRelations()
        {
            return new DbRelation[]
			{
			};
        }

        #endregion
    }
}
